/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package dyniablaster.logic;

import dyniablaster.graphics.*;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.*;
import java.util.Vector;

/**
 *
 * @author Damian2
 */
public class DyniaManager extends LayerManager
{
    int CANVAS_X;
    int CANVAS_Y;
    int DISP_WIDTH;
    int DISP_HEIGHT;
    int MIN_BUFFER = 60;
    int viewPortX = 0;
    int viewPortY = 0;
    int lastDirection = -1;
    int bombsTimes[] = {-1, -1, -1, -1, -1};

    private Timer timer;

    public 

    static int SPEED = 4;

    static int SQUARE_WIDTH = 16;

    DyniaBlasterCanvas myCanvas;
    DyniaBlasterDesign dyniaDesign;

    Sprite playerSprite;
    Sprite bomb;
    TiledLayer labirynt;
    TiledLayer floor;

    //Vector dyniaBombs;


    DyniaManager.SpriteAnimationTask playerSpriteAnimator;


    public DyniaManager(int x, int y, int width, int height, DyniaBlasterCanvas canvas) {
        myCanvas = canvas;
        CANVAS_X = x;
        CANVAS_Y = y;
        DISP_WIDTH = width;
        DISP_HEIGHT = height;
        timer = new Timer();
       // dyniaBombs = new Vector();
    }

    public void init() throws Exception
    {
        dyniaDesign = new DyniaBlasterDesign();
        playerSprite = dyniaDesign.getPlayer1();
        labirynt = dyniaDesign.getLabirynt();
        floor = dyniaDesign.getFloor();
        dyniaDesign.updateLayerManagerForScena(this);

        playerSpriteAnimator = new SpriteAnimationTask(playerSprite, false);
        timer.scheduleAtFixedRate(playerSpriteAnimator, 0, dyniaDesign.downDelay);


        viewPortX = playerSprite.getX() - ((DISP_HEIGHT - SQUARE_WIDTH) / 2);
        viewPortY = playerSprite.getY() - ((DISP_HEIGHT - SQUARE_WIDTH) / 2);


        System.gc();

    }

    public void paint(Graphics g) throws Exception
    {
        g.setColor(myCanvas.WHITE);
        // paint the background white to cover old game objects
        // that have changed position since last paint.
        // here coordinates are given
        // with respect to the graphics (canvas) origin:
        g.fillRect(0, 0, DISP_WIDTH, DISP_HEIGHT);
        // here coordinates are given
        // with respect to the LayerManager origin:
        setViewWindow(viewPortX, viewPortY, DISP_WIDTH, DISP_HEIGHT);
        // call the paint funstion of the superclass LayerManager
        // to paint all of the Layers
        
       
        paint(g, CANVAS_X, CANVAS_Y);
        g.setColor(myCanvas.BLACK);
        g.fillRect(0, 0, myCanvas.getWidth(), 15);
        g.setColor(myCanvas.WHITE);
        g.drawString(String.valueOf(bombsTimes[0]), myCanvas.getWidth() - 30, 0, Graphics.TOP | Graphics.LEFT);
    }

    public void update(int dt)
    {
        for(int i=0; i<5; i++)
        {
            if(bombsTimes[i] > 0)
            {
                bombsTimes[i] = bombsTimes[i] - dt;
                if(bombsTimes[i] <= 1000)
                    dyniaDesign.boom(i);

                if(bombsTimes[i] <= 0)
                {
                    dyniaDesign.destroyBomb(i);
                    bombsTimes[i] = -1;
                }
            }
        }

    }

    public void bomb() throws IOException
    {
        int sx = this.playerSprite.getX();
        int sy = this.playerSprite.getY();
        int i = dyniaDesign.setBomb(sx, sy);
        if(i >= 0)
        {
            bombsTimes[i] = 3000;
        }

    }

    private void adjustViewport(int x, int y)
    {

        int sx = this.playerSprite.getX();
        int sy = this.playerSprite.getY();

        int xmin = this.viewPortX + MIN_BUFFER;
        int xmax = this.viewPortX + myCanvas.getWidth() - this.playerSprite.getWidth() - MIN_BUFFER;
        int ymin = this.viewPortY + MIN_BUFFER;
        int ymax = this.viewPortY + myCanvas.getHeight() - this.playerSprite.getHeight() - MIN_BUFFER;

        //if the sprite is not near the any screen edges don't adjust
        if (sx >= xmin && sx <= xmax && sy >= ymin && sy <= ymax)
        {
            return;
        }

        //if the sprite is moving left but isn't near the left edge of the screen don't adjust
       /* if (this.lastDirection == LEFT && sx >= xmin) {
            return;
        }
        //if the sprite is moving right but isn't near the right edge of the screen don't adjust
        if (this.lastDirection == RIGHT && sx <= xmax) {
            return;
        }
        //if the sprite is moving up but isn't at near top edge of the screen don't adjust
        if (this.lastDirection == UP && sy >= ymin) {
            return;
        }
        //if the sprite is moving down but isn't at near bottom edge of the screen don't adjust
        if (this.lastDirection == DOWN && sy <= ymax) {
            return;
        }*/

        //only adjust x to values that ensure the base tiled layer remains visible
        //and no white space is shown
        if (x < this.floor.getX())
        {
            this.viewPortX = this.floor.getX();
        }
        else if (x > this.floor.getX() + this.floor.getWidth() - myCanvas.getWidth())
        {
            this.viewPortX = this.floor.getX() + this.floor.getWidth() - myCanvas.getWidth();
        }
        else
        {
            this.viewPortX = x;
        }

        //only adjust y to values that ensure the base tiled layer remains visible
        //and no white space is shown
        if (y < this.floor.getY())
        {
            this.viewPortY = this.floor.getY();
        } 
        else if (y > this.floor.getY() + this.floor.getHeight() - myCanvas.getHeight())
        {
            this.viewPortY = this.floor.getY() + this.floor.getHeight() - myCanvas.getHeight();
        }
        else
        {
            this.viewPortY = y;
        }

        //adjust the viewport
        this.setViewWindow(this.viewPortX, this.viewPortY, myCanvas.getWidth(), myCanvas.getHeight());
    }

    public void requestMove(int hdirection, int vdirection) {
        // vdirection < 0 indicates that the user has
        // pressed the UP button and would like to jump.
        // therefore, if we're not currently jumping,
        // we begin the jump.
        if(vdirection < 0)
        {
            playerSprite.move(0, -SPEED);
            if(playerSprite.collidesWith(labirynt, true))
                playerSprite.move(0, SPEED);
            else 
            {
                this.adjustViewport(this.viewPortX, this.viewPortY - SPEED);
                if (lastDirection != myCanvas.UP)
                {
                    this.lastDirection = myCanvas.UP;
                    this.playerSprite.setFrameSequence(dyniaDesign.goUp);
                    this.playerSprite.setTransform(Sprite.TRANS_NONE);
                    //continue;
                }
            }
            playerSpriteAnimator.forward();
            
        }
        else if(vdirection > 0)
        {
            playerSprite.move(0, SPEED);
            //lastDirection = myCanvas.DOWN;
            if(playerSprite.collidesWith(labirynt, true))
                playerSprite.move(0, -SPEED);
            else 
            {
                this.adjustViewport(this.viewPortX, this.viewPortY + SPEED);
                if (lastDirection != myCanvas.DOWN)
                {
                    this.lastDirection = myCanvas.DOWN;
                    this.playerSprite.setFrameSequence(dyniaDesign.goDown);
                    this.playerSprite.setTransform(Sprite.TRANS_NONE);
                    //continue;
                }
            }
            playerSpriteAnimator.forward();
            
        }
        else if (hdirection < 0)
        {
            playerSprite.move(-SPEED, 0);
            //lastDirection = myCanvas.LEFT;
            if(playerSprite.collidesWith(labirynt, true))
                playerSprite.move(SPEED, 0);
            else
            {
                this.adjustViewport(this.viewPortX - SPEED, this.viewPortY);
                if (lastDirection != myCanvas.RIGHT)
                {
                    this.lastDirection = myCanvas.RIGHT;
                    this.playerSprite.setFrameSequence(dyniaDesign.goLeft);
                    this.playerSprite.setTransform(Sprite.TRANS_NONE);
                    //continue;
                }
            }
            playerSpriteAnimator.forward();
            
        }
        else if(hdirection > 0)
        {
            playerSprite.move(SPEED, 0);
            //lastDirection = myCanvas.RIGHT;
            if(playerSprite.collidesWith(labirynt, true))
                playerSprite.move(-SPEED, 0);
            else
            {
                this.adjustViewport(this.viewPortX + SPEED, this.viewPortY);
                if (lastDirection != myCanvas.LEFT)
                {
                    this.lastDirection = myCanvas.LEFT;
                    this.playerSprite.setFrameSequence(dyniaDesign.goLeft);
                    this.playerSprite.setTransform(Sprite.TRANS_NONE);
                    //continue;
                }
            }
            playerSpriteAnimator.forward();
     
        }
        else
        {
            //playerSprite.setFrame(1);
            playerSpriteAnimator.setMoving(false);
        } 
    }

    private class SpriteAnimationTask extends TimerTask
    {

        private boolean moving = false;
        private boolean forward = true;
        private Sprite sprite;

        public SpriteAnimationTask(Sprite sprite, boolean forward)
        {
            this.sprite = sprite;
            this.forward = forward;
        }

        public void run()
        {
            if (!this.moving)
            {
                return;
            }
            if (this.forward)
            {
                this.sprite.nextFrame();
            }
            else
            {
                this.sprite.prevFrame();
            }
        }

        public void forward()
        {
            this.forward = true;
            this.moving = true;
        }

        public void backward()
        {
            this.forward = false;
            this.moving = true;
        }

        public void setMoving(boolean isMoving)
        {
            this.moving = isMoving;
        }
    }

}
